//
//  L0EntryTableController.m
//  L0EntryTable
//
//  Created by ∞ on 18/07/08.
//  Copyright 2008 Emanuele Vulcano. All rights reserved.
//

#import "L0EntryTableController.h"

@implementation L0EntryTableController

- (id) initWithNibName:(NSString*) name bundle:(NSBundle*) bundle {
	if (self = [super initWithNibName:name bundle:bundle]) {
		sections = [NSMutableArray new];
		self.entryAllowed = YES;
	}
	
	return self;
}

- (id) initWithCoder:(NSCoder*) c {
	if (self = [super initWithCoder:c]) {
		sections = [NSMutableArray new];
		self.entryAllowed = YES;
	}

	return self;
}

@synthesize entryAllowed, onscreen;

- (void) dealloc {
	[sections release];
	[super dealloc];
}

- (NSUInteger) countOfSections {
	return [sections count];
}

- (L0EntrySection*) objectInSectionsAtIndex:(NSUInteger) idx {
	return [sections objectAtIndex:idx];
}

- (void) insertObject:(L0EntrySection*) s inSectionsAtIndex:(NSUInteger) idx {
	[sections insertObject:s atIndex:idx];
	s.controller = self;
	if (onscreen) [self.tableView insertSections:[NSIndexSet indexSetWithIndex:idx] withRowAnimation:UITableViewRowAnimationFade];
}

- (void) removeObjectFromSectionsAtIndex:(NSUInteger) idx {
	L0EntrySection* s = [sections objectAtIndex:idx];
	s.controller = nil;
	
	[sections removeObjectAtIndex:idx];
	if (onscreen) [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:idx] withRowAnimation:UITableViewRowAnimationFade];
}

@synthesize tableView;
- (void) setTableView:(UITableView*) t {
	if (tableView != t) {
		[tableView release];
		tableView = [t retain];
		
		tableView.dataSource = self;
		tableView.delegate = self;
		[tableView reloadData];
	}
}

- (NSInteger) numberOfSectionsInTableView:(UITableView*) table {
	if ([self countOfSections] == 0)
		return 1;
	else
		return [self countOfSections];
}

- (NSInteger) tableView:(UITableView*) table numberOfRowsInSection:(NSInteger) section {
	if ([self countOfSections] == 0)
		return 0;
	
	return [[self objectInSectionsAtIndex:section] countOfCells];
}

- (UITableViewCell*) tableView:(UITableView*) tableView cellForRowAtIndexPath:(NSIndexPath*) indexPath {
	return (UITableViewCell*) [[self objectInSectionsAtIndex:[indexPath section]] objectInCellsAtIndex:[indexPath row]];
}

- (void) selectCellAtIndex:(NSUInteger) idx inSection:(L0EntrySection*) s {
	NSUInteger section = [sections indexOfObject:s];
	NSAssert(section != NSNotFound, @"You must use a section that is actually contained in the sections key of this controller.");
	
	[self.tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:idx inSection:section] animated:NO scrollPosition:UITableViewScrollPositionMiddle];
}

- (NSUInteger) indexOfObjectInSections:(L0EntrySection*) s {
	return [sections indexOfObject:s];
}


- (void) viewWillAppear:(BOOL) ani {
	[self.tableView reloadData];
}

- (void) viewDidAppear:(BOOL) ani {
	onscreen = YES;

	NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
	[center addObserver:self selector:@selector(_keyboardWillAppear:) name:UIKeyboardWillShowNotification object:nil];
	[center addObserver:self selector:@selector(_keyboardDidAppear:) name:UIKeyboardDidShowNotification object:nil];
	[center addObserver:self selector:@selector(_keyboardWillDisappear:) name:UIKeyboardWillHideNotification object:nil];
}

- (void) viewDidDisappear:(BOOL) ani {
	onscreen = NO;
	
	NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
	[center removeObserver:self name:UIKeyboardWillShowNotification object:nil];
	[center removeObserver:self name:UIKeyboardDidShowNotification object:nil];
	[center removeObserver:self name:UIKeyboardWillHideNotification object:nil];
}

- (void) _keyboardWillAppear:(NSNotification*) n {
	NSLog(@"Keyboard is about to appear");
}

- (void) _keyboardDidAppear:(NSNotification*) n {
	CGRect bounds = [[[n userInfo] objectForKey:UIKeyboardBoundsUserInfoKey] CGRectValue];
	bounds = [self.view convertRect:bounds fromView:nil];
	
	CGRect tableFrame = self.view.bounds;
	tableFrame.size.height -= bounds.size.height;
	
	[UIView beginAnimations:nil context:NULL];

		[UIView setAnimationDelegate:self];
		[UIView setAnimationDidStopSelector:@selector(_shrinkDidEnd:finished:contextInfo:)];
		self.tableView.frame = tableFrame;

	[UIView commitAnimations];
	
	//[self hideEditorView:currentEditorView];
	[currentEditorView removeFromSuperview];
}

- (void) _shrinkDidEnd:(NSString*) ident finished:(BOOL) finished contextInfo:(void*) nothing {
	NSIndexPath* sel = [self.tableView indexPathForSelectedRow];
	if (![[self.tableView indexPathsForVisibleRows] containsObject:sel])
		[self.tableView scrollToNearestSelectedRowAtScrollPosition:UITableViewScrollPositionMiddle animated:YES];
}

- (void) _keyboardWillDisappear:(NSNotification*) n {
	self.tableView.frame = self.view.bounds;
	
	[self.tableView scrollToNearestSelectedRowAtScrollPosition:UITableViewScrollPositionMiddle animated:YES];
}

- (void) deselect {
	NSIndexPath* path = [self.tableView indexPathForSelectedRow];
	if (path) [self.tableView deselectRowAtIndexPath:path animated:YES];
}

#define L0BottomLeftCornerOfRect(rect) CGPointMake(CGRectGetMinX((rect)), CGRectGetMaxY((rect)));

- (void) displayEditorView:(UIView*) editorView {
	if (!editorView || editorView == currentEditorView) return;
	
	CGRect tableFrame = self.view.bounds;

	CGRect editorFrame = editorView.frame;
	editorFrame.size.width = tableFrame.size.width;
	editorFrame.origin = L0BottomLeftCornerOfRect(self.view.bounds);
	
	tableFrame.size.height -= editorFrame.size.height;
	
	editorView.frame = editorFrame;
	[self.view insertSubview:editorView aboveSubview:self.tableView];
	
	NSValue* tableFrameObject = [NSValue valueWithCGRect:tableFrame];
	
	[UIView beginAnimations:nil context:[tableFrameObject retain]];
	
		[UIView setAnimationDelegate:self];
		[UIView setAnimationDidStopSelector:@selector(_displayEditorAnimationDidEnd:finished:tableFrame:)];

		[self hideEditorView:currentEditorView];
		
		editorFrame.origin.y -= editorFrame.size.height;
		editorView.frame = editorFrame;
	
	[UIView commitAnimations];
	
	currentEditorView = editorView;
}

- (void) _displayEditorAnimationDidEnd:(NSString*) name finished:(BOOL) finished tableFrame:(NSValue*) tableFrameObject {
	[tableFrameObject autorelease];
	CGRect tableFrame = [tableFrameObject CGRectValue];
	
	self.tableView.frame = tableFrame;

	[self performSelector:@selector(_scrollToInvisibleSelection) withObject:nil afterDelay:0.05];
}

- (void) _scrollToInvisibleSelection {
	
	NSIndexPath* sel = [self.tableView indexPathForSelectedRow];
	if (![[self.tableView indexPathsForVisibleRows] containsObject:sel])
		[self.tableView scrollToNearestSelectedRowAtScrollPosition:UITableViewScrollPositionMiddle animated:YES];
	
}

- (void) _hideEditorAnimationDidEnd:(NSString*) name finished:(BOOL) finished forEditorView:(UIView*) view {
	[view removeFromSuperview];
}

- (void) hideEditorView:(UIView*) editorView {
	if (!editorView || editorView != currentEditorView) return;
	if (aboutToBeSetUp.displaysKeyboardOnSetUp) return; // the keyboard display code will handle this.
	
	[UIView beginAnimations:nil context:currentEditorView];
	[UIView setAnimationDelegate:self];
	[UIView setAnimationDidStopSelector:@selector(_hideEditorAnimationDidEnd:finished:forEditorView:)];

		CGRect slideOutFrame = currentEditorView.frame;
		slideOutFrame.origin = L0BottomLeftCornerOfRect(self.view.bounds);

	[UIView commitAnimations];
	
	currentEditorView = nil;
}

- (NSIndexPath*) tableView:(UITableView*) table willSelectRowAtIndexPath:(NSIndexPath*) indexPath {
	
	NSIndexPath* current = [self.tableView indexPathForSelectedRow];
	aboutToBeSetUp = (L0EntryCell*) (self.entryAllowed? [self.tableView cellForRowAtIndexPath:indexPath] : nil);
	if (![current isEqual:indexPath])
		[(L0EntryCell*)[self.tableView cellForRowAtIndexPath:current] tearDownEditing];
	
	aboutToBeSetUp = nil;
	return self.entryAllowed? indexPath : nil;
	
}

- (void) tableView:(UITableView*) tableView didSelectRowAtIndexPath:(NSIndexPath*) indexPath {
	[(L0EntryCell*)[self.tableView cellForRowAtIndexPath:indexPath] setUpEditing];
}

@end
